Method and apparatus for inserting faults to test code paths

ABSTRACT

One embodiment of the present invention provides a system that inserts faults to test code paths. The system starts by placing fault-inserting method calls at join points within methods in program code. The system then executes the program code during a testing process. As a method is executed during the testing process, the system executes the corresponding fault-inserting method. This fault-inserting method checks a configuration database to determine whether a fault is to be simulated for the method and, if so, simulates a fault for the method.

BACKGROUND Related Art

Software is commonly designed to deal with problems at runtime, such asusers performing impermissible actions or computer systems encounteringerror conditions. For example, a user may enter a numerical characterinto a field that is intended for only alphabetical characters.Alternatively, the computer system can fail to obtain (or lose) anetwork connection or the computer system hardware can malfunction.

Because the software inevitably encounters such problems, programmersattempt to design software that handles these problems as gracefully aspossible. Unfortunately, software projects are often developed bymultiple teams, working at different locations, with varying levels ofcompetency and varying levels of compliance with project-levelerror-handling requirements. Consequently, errors may not be handledcorrectly or consistently. Furthermore, a project may involveincremental extensions of enormous bodies of legacy code, which involvescombining new code with old code. Therefore, developing proper testsequences to assure that all error paths are exercised can be verydifficult. Hence, software projects may be released with a significantnumber of error paths that are untested.

Hence, what is needed is a method and apparatus for testing softwarewithout the above-described problem.

SUMMARY

One embodiment of the present invention provides a system that insertsfaults to test code paths. The system starts by placing fault-insertingmethod calls at join points within methods in program code. The systemthen executes the program code during a testing process. As a method isexecuted during the testing process, the system executes thecorresponding fault-inserting method. This fault-inserting method checksa configuration database to determine whether a fault is to be simulatedfor the method and, if so, simulates a fault for the method.

In a variation of this embodiment, the configuration database containsentries for methods in the program code, wherein each entry includes avalue that corresponds to a fault.

In a variation of this embodiment, simulating a fault involves throwingan exception or returning an error code corresponding to a value storedin the configuration database.

In a variation of this embodiment, the system determines a set ofexceptions that can be thrown and determines return codes that can bereturned from each method in the program code. The system then generatesan exceptions/returns database, wherein the exceptions/returns databasecontains entries for methods, and wherein the entries specify exceptionsthat can be thrown and return codes that can be returned from themethod.

In a variation of this embodiment, the system uses theexceptions/returns database to create test paths in the program code.

In a variation of this embodiment, the system permits a tester todynamically modify the configuration database during the testingprocess, wherein modifying the configuration database allows a tester tosimulate a fault for at least one method during the testing process.

In a variation of this embodiment, the system permits a tester tostatically modify a configuration file which serves as the configurationdatabase before running the program code during the testing process.

In a variation of this embodiment, the program code can be executablecode or source code.

BRIEF DESCRIPTION OF THE FIGURES

FIG. 1 illustrates testing system in accordance with an embodiment ofthe present invention.

FIG. 2A illustrates a GetConnection method which serves as the joinpoint for the placement of an “advice” in accordance with an embodimentof the present invention.

FIG. 2B illustrates pseudocode for an exemplary FaultInserter method inaccordance with an embodiment of the present invention.

FIG. 3 presents a flowchart that illustrates the insertion of faults totest code paths accordance with an embodiment of the present invention.

DETAILED DESCRIPTION

The following description is presented to enable any person skilled inthe art to make and use the invention, and is provided in the context ofa particular application and its requirements. Various modifications tothe disclosed embodiments will be readily apparent to those skilled inthe art, and the general principles defined herein may be applied toother embodiments and applications without departing from the spirit andscope of the present invention. Thus, the present invention is notlimited to the embodiments shown, but is to be accorded the widest scopeconsistent with the claims.

The data structures and code described in this detailed description aretypically stored on a computer-readable storage medium, which may be anydevice or medium that can store code and/or data for use by a computersystem. This includes, but is not limited to, magnetic and opticalstorage devices such as disk drives, magnetic tape, CDs (compact discs),DVDs (digital versatile discs or digital video discs), or any devicecapable of storing data usable by a computer system.

Fault Inserter

FIG. 1 illustrates testing system 100 in accordance with an embodimentof the present invention. Testing system 100 includes user interface102, central processing unit (CPU) 104, and memory 106. CPU 104 can beany type of general-purpose microprocessor(s) that execute(s) programcode. Memory 106 contains data and program code for CPU 104. In oneembodiment of the present invention, memory 106 includes program codefor a program that is to be tested and a configuration database that isused during the testing process. User interface 102 allows user tocommunicate commands to and receive information from testing system 100during the testing process.

In one embodiment of the present invention, testing system 100 is awhite-box testing solution based on Aspect-Oriented Programming (AOP)and Reflection. In this embodiment, Reflection is used to build up an“exceptions/returns” database that contains every exception that isexplicitly thrown from every method under test, plus every return codethat is returned from every method under test. Testing system 100 canthen use the exceptions/returns database to facilitate creating testpaths to assure that the fault testing includes as many of the potentialfault paths as possible.

In addition to creating the exceptions/returns database, AOP is used toinsert an “advice” at a “join point” corresponding to every method undertest. Note that in the AOP model, a “join point” is a point in a programwhere additional behavior (e.g., the simulation of a fault) can beusefully joined, whereas an “advice” is a mechanism for specifying codeto run at a join point. For example, FIG. 2A illustrates a GetConnectionmethod which serves as the join point for the placement of an “advice”in accordance with an embodiment of the present invention. Before theadvice is joined, the GetConnection method includes only the coderequired by the method (as shown by initial code 200). An AOP softwaretool (such as AspectJ by the Eclipse Project or Spring by Interface 21)is then run on the method. The AOP tool modifies the GetConnectionmethod to include an advice (i.e., the method call) related to theinsertion of faults. Hence, after the AOP tool is run, the GetConnectionmethod includes a call to the FaultInserter method (as shown infault-decorated code 202).

FIG. 2B illustrates an exemplary pseudocode FaultInserter method inaccordance with an embodiment of the present invention. Duringoperation, the FaultInserter method checks the configuration databasestored in memory 106 to see if the corresponding MethodName method issupposed to be faulted during the current testing and, if so, what formthe faulting should take (i.e., whether to return a particular errorcode or to throw a particular exception).

In one embodiment of the present invention, the configuration databaseis stored in a data structure in memory 106 that can be modifiedon-the-fly, allowing a user to direct testing system 100 to cause faultsin selected methods while the test is being run. In an alternativeembodiment, the user places entries corresponding to the selectedmethods in a configuration file before testing the program. Testingsystem 100 then reads the file during the testing process and faults theselected methods. In both embodiments, the user also enters the type offault that testing system 100 uses to fault a selected method.

In one embodiment of the present invention the fault can be set to berandom, in which case any one of the exceptions the method throws can bethrown or any one of the error codes the method returns can be returned.In an alternative embodiment, testing system 100 iterates through eachexception and each returned error code in turn. Running a suite of testsagainst a system faulted in this way can cause many or allerror-handling paths to be exercised. Note that in these embodiments,the exceptions/returns database can be used to select exceptions orerror codes corresponding to the method.

In another embodiment of the present invention, exceptions and errorcodes known to be thrown or returned from libraries linked into the codeunder test can be simulated without replacing or altering the linked-inlibraries in any way. (Note that this is a significant advantagecompared to, for example, using interfaces and providing faultedconcrete implementations of those interfaces at runtime). Furthermore,exceptions and error codes that aren't even possible can be thrown orreturned, in order to test completely unexpected behavior.

Note that some embodiments of testing system 100 work better forexceptions than for return codes, because determining by Reflection whena return value is non-erroneous vs. erroneous is not always possible.Hence, testing system 100 sometimes returns values indicating success,which does not exercise error paths. In this embodiment, repeatedexecution of tests with the mode set to random eventually overcomes thisproblem (i.e., eventually error codes are returned instead of successcodes). In an alternative embodiment, if a design project standardizesreturn codes, this information can be added to the database in order toreturn only codes indicating errors.

Testing Code

FIG. 3 presents a flowchart that illustrates the insertion of faults totest code paths in accordance with an embodiment of the presentinvention. The process starts when testing system 100 executes programcode during a testing mode (step 300). For the purposes of illustration,we assume that the program code has already been modified using an AOPtool in a “static” or “offline” mode. Hence, the AOP tool has modifiedthe classes to include the advice related to the insertion of faults(i.e., the call to the FaultInserter method) at the correct point-cuts.However, in an alternative embodiment, the AOP tool can run in a“dynamic” or “online” mode. In this embodiment, the AOP tool can be runas an extension of the low-level classloading mechanism part of the JavaVirtual Machine (JVM), allowing the AOP tool to intercept allclassloading calls and transform the bytecode on the fly.

Unless testing system 100 encounters a method call (step 302), testingsystem 100 returns to step 300 to continue to execute program code inthe testing mode. If testing system 100 encounters a method call,testing system 100 executes the call to the FaultInserter method thatwas placed by the AOP tool at the start of each method under test (step304). The FaultInserter method determines if the method name (see“MethodName” in FIG. 2B) is included in the configuration database (step306). If the configuration database does not include the method's name,the method is not currently to be faulted and testing system 100 returnsto step 300 to continue to execute program code in the testing mode.

Otherwise, the FaultInserter method reads the configuration database todetermine how the method is to be faulted. If the configuration databaseindicates that the method should appear to throw an exception (step308), the FaultInserter method throws the exception (step 310).Otherwise, the method should return a value that makes it appear as ifthe method encountered an error. In this case, the FaultInserter methodreturns the corresponding value to the method (step 312). The methodthen returns this value, making it appear as if the method hadencountered the corresponding error condition. Testing system 100 thenreturns to step 300 to continue executing program code in the testingmode.

The foregoing descriptions of embodiments of the present invention havebeen presented only for purposes of illustration and description. Theyare not intended to be exhaustive or to limit the present invention tothe forms disclosed. Accordingly, many modifications and variations willbe apparent to practitioners skilled in the art. Additionally, the abovedisclosure is not intended to limit the present invention. The scope ofthe present invention is defined by the appended claims.

What is claimed is:
 1. A method for inserting faults to test code paths, comprising: placing fault-inserting method calls at join points in methods in program code; executing the program code during a testing process; and as a method is executed during the testing process, executing the corresponding fault-inserting method, wherein the fault-inserting method checks a configuration database to determine whether a fault is to be simulated for the method and, if so, simulates a fault for the method, wherein simulating the fault for the method comprises: determining whether an entry for the method in the configuration database indicates that the method should appear to throw an exception that is known to be thrown for the method or return an error code that is known to be returned for the method; when the entry indicates that the method should appear to throw the exception, simulating the fault by using the fault-inserting method to throw the exception; and otherwise, when the entry indicates that the method should appear to return the error code, simulating the fault by using the fault-inserting method to return the error code to the method.
 2. The method of claim 1, wherein the configuration database contains entries for methods in the program code, wherein each entry includes a value that corresponds to a fault.
 3. The method of claim 2, wherein using the fault-inserting method to throw the exception comprises throwing the exception based on a value for the entry stored in the configuration database, and wherein using the fault-inserting method to return the error code to the method comprises returning the error code based on a value for the entry stored in the configuration database.
 4. The method of claim 1, wherein the method further comprises: determining a set of exceptions that can be thrown and determining return codes that can be returned from each method in the program code; and generating an exceptions/returns database, wherein the exceptions/returns database contains entries for the methods, wherein the entries in the exceptions/returns database specify exceptions that can be thrown and return codes that can be returned from the method.
 5. The method of claim 4, wherein the method further comprises using the exceptions/returns database to create test paths in the program code.
 6. The method of claim 1, wherein the method further comprises statically modifying a configuration file which serves as the configuration database before running the program code during the testing process.
 7. The method of claim 1, wherein the program code can be compiled code or source code.
 8. The method of claim 1, wherein using the fault-inserting method to throw the exception comprises running code for the fault-inserting method that causes the exception to be thrown.
 9. The method of claim 1, wherein the method further comprises: determining whether an entry in the configuration database for a library that is used in the program code indicates that a library should appear to throw an exception that is known to be thrown for the library or return an error code that is known to be returned for the library; when the entry for the library indicates that the library should appear to throw the exception, simulating the fault by using the fault-inserting method to throw the exception; and otherwise, when the entry for the library indicates that the library should appear to return the error code, simulating the fault by using the fault-inserting method to return the error code to the method, wherein the method does not involve replacing the library and does not involve altering the library.
 10. An apparatus for inserting faults to test code paths, comprising: a processor; an execution mechanism on the processor; a memory coupled to the processor, wherein the memory stores data and program code for the processor; a configuration database in the memory, wherein the configuration database contains entries for methods in the program code, wherein each entry includes a value that corresponds to a fault; a placement mechanism configured to place fault-inserting method calls at join points in methods in program code; wherein the execution mechanism is configured to: execute the program code during a testing process; while executing a method during the testing process, execute the corresponding fault-inserting method, wherein executing the fault-inserting method causes the execution mechanism to check the configuration database to determine whether a fault is to be simulated for the method and, if so, the execution mechanism is configured to simulate a fault for the method, wherein, while simulating the fault for the method, the execution mechanism is configured to: determine whether an entry for the method in the configuration database indicates that the method should appear to throw an exception that is known to be thrown for the method or return an error code that is known to be returned for the method; when the entry indicates that the method should appear to throw the exception, simulate the fault by using the fault-inserting method to throw the exception; and otherwise, when the entry indicates that the method should appear to return the error code, simulate the fault by using the fault-inserting method to return the error code to the method.
 11. The apparatus of claim 10, wherein the execution mechanism is configured to: determine a set of exceptions that can be thrown and determine return codes that can be returned from each method in the program code; create test paths in the program code based in part on the exceptions/returns database, wherein the entries in the exceptions/returns database specify exceptions that can be thrown and return codes that can be returned from the method.
 12. The apparatus of claim 10, wherein, while using the fault-inserting method to throw the exception, the execution mechanism is configured to use a value for the entry stored in the configuration database, and wherein, while using the fault-inserting method to return the error code, the execution mechanism is configured to return the error code based on a value for the entry stored in the configuration database.
 13. A computer-readable storage medium storing instructions that when executed by a computer cause the computer to perform a method for inserting faults to test code paths, comprising: placing fault-inserting method calls at a join points in methods in program code; executing the program code during a testing process; and as a method is executed during the testing process, executing the corresponding fault-inserting method, wherein the fault-inserting method checks a configuration database to determine whether a fault is to be simulated for the method and, if so, simulating a fault for the method, wherein simulating the fault for the method comprises: determining whether an entry for the method in the configuration database indicates that the method should appear to throw an exception that is known to be thrown for the method or return an error code that is known to be returned for the method; when the entry indicates that the method should appear to throw the exception, simulating the fault by using the fault-inserting method to throw the exception; and otherwise, when the entry indicates that the method should appear to return the error code, simulating the fault by using the fault-inserting method to return the error code to the method.
 14. The computer-readable storage medium of claim 13, wherein the configuration database contains entries for methods in the program code, wherein each entry includes a value that corresponds to a fault.
 15. The computer-readable storage medium of claim 14, wherein using the fault-inserting method to throw the exception comprises throwing the exception based on a value for the entry stored in the configuration database, and wherein using the fault-inserting method to return the error code to the method comprises returning the error code based on a value for the entry stored in the configuration database.
 16. The computer-readable storage medium of claim 13, wherein the method further comprises: determining a set of exceptions that can be thrown and determining return codes that can be returned from each method in the program code; generating an exceptions/returns database, wherein the exceptions/returns database contains entries for the methods in the program code, wherein the entries in the exceptions/returns database specify exceptions that can be thrown and return codes that can be returned from the method.
 17. The computer-readable storage medium of claim 13, wherein the method further comprises statically modifying a configuration file which serves as the configuration database before running the program code during the testing process. 